package com.tsingtree.sys.modular.system.service.impl;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.tsingtree.sys.modular.system.service.IRedisUtilService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * Redis 工具类
 */
@Service
public class RedisUtilServiceImpl implements IRedisUtilService {

    private final RedisTemplate<String, String> stringRedisTemplate;

    public RedisUtilServiceImpl(RedisTemplate<String, String> stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    public void set(String key,String value){
        stringRedisTemplate.opsForValue().set(key, value);
    }

    public void hSet(String key, String m, String value){
        stringRedisTemplate.opsForHash().put(key, m, value);
    }

    @Override
    public Object hGet(String key, String m) {
        return stringRedisTemplate.opsForHash().get(key, m);
    }

    @Override
    public Boolean zAdd(String key, String value, double score) {
        return stringRedisTemplate.opsForZSet().add(key, value, score);
    }

    @Override
    public Set<String> zRange(String key, long start, long end) {
        return stringRedisTemplate.opsForZSet().range(key, start, end);
    }

    @Override
    public Set<ZSetOperations.TypedTuple<String>> zRangeWithScores(String key, long start, long end) {
        return stringRedisTemplate.opsForZSet().rangeWithScores(key, start, end);
    }

    @Override
    public Set<String> zRangeByScores(String key, long start, long end) {
        return stringRedisTemplate.opsForZSet().rangeByScore(key, start, end);
    }

    @Override
    public Set<String> zRevRange(String key, long start, long end) {
        return stringRedisTemplate.opsForZSet().reverseRange(key, start, end);
    }

    @Override
    public Long zRemove(String key, String value) {
        return stringRedisTemplate.opsForZSet().remove(key, value);
    }

    @Override
    public Boolean zRemoveByScore(String key, double score) {
        return stringRedisTemplate.opsForZSet().removeRangeByScore(key, score, score) != 0;
    }

    @Override
    public Long zRemoveRange(String key, int start, int end) {
        return stringRedisTemplate.opsForZSet().removeRange(key, start, end);
    }

    @Override
    public Long zCard(String key) {
        return stringRedisTemplate.opsForZSet().zCard(key);
    }

    @Override
    public Boolean hasKey(String key) {
        return stringRedisTemplate.hasKey(key);
    }

    public String get(String key){
        return stringRedisTemplate.opsForValue().get(key);
    }

    public void setForTimeHour(String key,String value,long time){
        stringRedisTemplate.opsForValue().set(key, value, time, TimeUnit.HOURS);
    }

    @Override
    public void setForTimeMinute(String key, String value, long time) {
        stringRedisTemplate.opsForValue().set(key, value, time, TimeUnit.MINUTES);
    }

    public void setForTimeSecond(String key,String value,long time){
        stringRedisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
    }

    public void put(String key, String hashKey, String value){
        stringRedisTemplate.opsForHash().put(key, hashKey, value);
    }

    public  void putAll(String key, Map<String, Map<String, String>> map){
        stringRedisTemplate.opsForHash().putAll(key, map);
    }

    public Long delete(String key, String ...hashKeys) {
        return stringRedisTemplate.opsForHash().delete(key, (Object) hashKeys);
    }

    public void delete(String key) {
        stringRedisTemplate.delete(key);
    }

    @Override
    public Long incr(String s) {
        return stringRedisTemplate.opsForValue().increment(s);
    }

    @Override
    public BigDecimal getCoinPrice(String coinName) {
        String price = this.get("price:" + coinName);
        if(StringUtils.isEmpty(price)) return BigDecimal.ZERO;
        return new BigDecimal(price);
    }

}
